JavaScriptãã³ã¬ãŒã¿ãã¡ã¿ããŒã¿ããªãã¬ã¯ã·ã§ã³ãæ¢æ±ãã匷åãªã©ã³ã¿ã€ã ã¡ã¿ããŒã¿ã¢ã¯ã»ã¹ãè§£ãæŸã¡ãé«åºŠãªæ©èœãä¿å®æ§ã®åäžãã¢ããªã±ãŒã·ã§ã³ã«ãããæè»æ§ã®åäžãå®çŸããŸãã
JavaScriptãã³ã¬ãŒã¿ãã¡ã¿ããŒã¿ããªãã¬ã¯ã·ã§ã³ïŒæ©èœåŒ·åã®ããã®ã©ã³ã¿ã€ã ã¡ã¿ããŒã¿ã¢ã¯ã»ã¹
åæã®ã¹ã¯ãªããã®åœ¹å²ãè¶ ããŠé²åãç¶ããJavaScriptã¯ãçŸåšãè€éãªWebã¢ããªã±ãŒã·ã§ã³ãšãµãŒããŒãµã€ãç°å¢ãæ¯ããŠããŸãã ãã®é²åã«ã¯ãè€éãã管çããä¿å®æ§ãé«ããã³ãŒãã®åå©çšæ§ãä¿é²ããããã®é«åºŠãªããã°ã©ãã³ã°æè¡ãå¿ èŠã§ãã Stage 2 ECMAScriptææ¡ã§ãããã³ã¬ãŒã¿ã¯ãã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ãšçµã¿åãããããšã§ãã©ã³ã¿ã€ã ã¡ã¿ããŒã¿ã¢ã¯ã»ã¹ãšã¢ã¹ãã¯ãæåããã°ã©ãã³ã°ïŒAOPïŒãã©ãã€ã ãå¯èœã«ãããããã®ç®æšãéæããããã®åŒ·åãªã¡ã«ããºã ãæäŸããŸãã
ãã³ã¬ãŒã¿ã®çè§£
ãã³ã¬ãŒã¿ã¯ãã¯ã©ã¹ãã¡ãœãããããããã£ããŸãã¯ãã©ã¡ãŒã¿ã®åäœã倿ŽãŸãã¯æ¡åŒµããããã®ç°¡æœã§å®£èšçãªæ¹æ³ãæäŸããæ§æç³è¡£ã§ãã ãã³ã¬ãŒã¿ã¯ã@èšå·ãåã«ä»ããè£
食ããèŠçŽ ã®çŽåã«é
眮ããã颿°ã§ãã ããã«ãããè£
食ãããèŠçŽ ã®ã³ã¢ããžãã¯ãçŽæ¥å€æŽããããšãªãããã®ã³ã°ãæ€èšŒãæ¿èªãªã©ã®ã¯ãã¹ã»ã«ããã£ã³ã°ã»ã³ã³ãµãŒã³ã远å ã§ããŸãã
ç°¡åãªäŸãèããŠã¿ãŸãããã ç¹å®ã®ã¡ãœãããåŒã³åºããããã³ã«ãã°ãèšé²ããå¿
èŠããããšããŸãã ãã³ã¬ãŒã¿ã䜿çšããªãå Žåã¯ãåã¡ãœããã«ãã°èšé²ããžãã¯ãæåã§è¿œå ããå¿
èŠããããŸãã ãã³ã¬ãŒã¿ã䜿çšãããšã@logãã³ã¬ãŒã¿ãäœæãããã°ãèšé²ããã¡ãœããã«é©çšã§ããŸãã ãã®ã¢ãããŒãã«ããããã°èšé²ããžãã¯ãã³ã¢ã¡ãœããããžãã¯ããåé¢ããã³ãŒãã®å¯èªæ§ãšä¿å®æ§ãåäžããŸãã
ãã³ã¬ãŒã¿ã®çš®é¡
JavaScriptã«ã¯4çš®é¡ã®ãã³ã¬ãŒã¿ãããããããããç°ãªãç®çãæãããŸãã
- ã¯ã©ã¹ãã³ã¬ãŒã¿ïŒãããã®ãã³ã¬ãŒã¿ã¯ãã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿ã倿ŽããŸãã æ°ããããããã£ãã¡ãœããã远å ããããæ¢åã®ããããã£ãã¡ãœããã倿Žãããããããã«äœ¿çšã§ããŸãã
- ã¡ãœãããã³ã¬ãŒã¿ïŒãããã®ãã³ã¬ãŒã¿ã¯ãã¡ãœããã®åäœã倿ŽããŸãã ã¡ãœããã®å®è¡ã®ååŸã«ããã®ã³ã°ãæ€èšŒããŸãã¯æ¿èªããžãã¯ã远å ããããã«äœ¿çšã§ããŸãã
- ããããã£ãã³ã¬ãŒã¿ïŒãããã®ãã³ã¬ãŒã¿ã¯ãããããã£ã®èšè¿°åã倿ŽããŸãã ããŒã¿ãã€ã³ãã£ã³ã°ãæ€èšŒããŸãã¯é å»¶åæåãå®è£ ããããã«äœ¿çšã§ããŸãã
- ãã©ã¡ãŒã¿ãã³ã¬ãŒã¿ïŒãããã®ãã³ã¬ãŒã¿ã¯ãã¡ãœããã®ãã©ã¡ãŒã¿ã«é¢ããã¡ã¿ããŒã¿ãæäŸããŸãã ãã©ã¡ãŒã¿ã®åãå€ã«åºã¥ããŠäŸåæ§æ³šå ¥ãæ€èšŒããžãã¯ãå®è£ ããããã«äœ¿çšã§ããŸãã
åºæ¬çãªãã³ã¬ãŒã¿ã®æ§æ
ãã³ã¬ãŒã¿ã¯ãè£ é£ŸãããèŠçŽ ã®ã¿ã€ãã«å¿ããŠã1ã€ã2ã€ããŸãã¯3ã€ã®åŒæ°ãåã颿°ã§ãã
- ã¯ã©ã¹ãã³ã¬ãŒã¿ïŒã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿ãåŒæ°ãšããŠåããŸãã
- ã¡ãœãããã³ã¬ãŒã¿ïŒ3ã€ã®åŒæ°ãåããŸããã¿ãŒã²ãããªããžã§ã¯ãïŒéçã¡ã³ããŒã®å Žåã¯ã³ã³ã¹ãã©ã¯ã¿é¢æ°ãã€ã³ã¹ã¿ã³ã¹ã¡ã³ããŒã®å Žåã¯ã¯ã©ã¹ã®ãããã¿ã€ãïŒãã¡ã³ããŒã®ååãããã³ã¡ã³ããŒã®ããããã£èšè¿°åã
- ããããã£ãã³ã¬ãŒã¿ïŒ2ã€ã®åŒæ°ãåããŸããã¿ãŒã²ãããªããžã§ã¯ããšããããã£ã®ååã
- ãã©ã¡ãŒã¿ãã³ã¬ãŒã¿ïŒ3ã€ã®åŒæ°ãåããŸããã¿ãŒã²ãããªããžã§ã¯ããã¡ãœããã®ååãããã³ã¡ãœããã®ãã©ã¡ãŒã¿ãªã¹ãå ã®ãã©ã¡ãŒã¿ã®ã€ã³ããã¯ã¹ã
ã·ã³ãã«ãªã¯ã©ã¹ãã³ã¬ãŒã¿ã®äŸã次ã«ç€ºããŸãã
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@sealed
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
ãã®äŸã§ã¯ã@sealedãã³ã¬ãŒã¿ãGreeterã¯ã©ã¹ã«é©çšãããŠããŸãã sealed颿°ã¯ãã³ã³ã¹ãã©ã¯ã¿ãšãã®ãããã¿ã€ãã®äž¡æ¹ãããªãŒãºãããã以äžã®å€æŽãé²ããŸãã ããã¯ãç¹å®ã®ã¯ã©ã¹ã®äžå€æ§ã確ä¿ããã®ã«åœ¹ç«ã¡ãŸãã
ã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã®å
ã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã¯ãã©ã³ã¿ã€ã æã«ã¯ã©ã¹ãã¡ãœãããããããã£ãããã³ãã©ã¡ãŒã¿ã«é¢é£ä»ããããã¡ã¿ããŒã¿ã«ã¢ã¯ã»ã¹ããæ¹æ³ãæäŸããŸãã ããã«ãããäŸåæ§æ³šå
¥ãã·ãªã¢ã«åãæ€èšŒãªã©ã®åŒ·åãªæ©èœãå¯èœã«ãªããŸãã JavaScriptèªäœã¯ãJavaãC#ãªã©ã®èšèªãšåãæ¹æ³ã§æ¬è³ªçã«ãªãã¬ã¯ã·ã§ã³ããµããŒãããŠããŸããã ãã ããreflect-metadataã®ãããªã©ã€ãã©ãªããã®æ©èœãæäŸããŸãã
Ron Bucktonãéçºããreflect-metadataã©ã€ãã©ãªã䜿çšãããšããã³ã¬ãŒã¿ã䜿çšããŠã¡ã¿ããŒã¿ãã¯ã©ã¹ãšãã®ã¡ã³ããŒã«æ·»ä»ããã©ã³ã¿ã€ã æã«ãã®ã¡ã¿ããŒã¿ãååŸã§ããŸãã ããã«ãããããæè»ã§èšå®å¯èœãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã
reflect-metadataã®ã€ã³ã¹ããŒã«ãšã€ã³ããŒã
reflect-metadataã䜿çšããã«ã¯ãæåã«npmãŸãã¯yarnã䜿çšããŠã€ã³ã¹ããŒã«ããå¿
èŠããããŸãã
npm install reflect-metadata --save
ãŸãã¯yarnã䜿çšããŸãã
yarn add reflect-metadata
次ã«ããããžã§ã¯ãã«ã€ã³ããŒãããå¿
èŠããããŸãã TypeScriptã§ã¯ãã¡ã€ã³ãã¡ã€ã«ïŒäŸïŒindex.tsãŸãã¯app.tsïŒã®å
é ã«æ¬¡ã®è¡ã远å ã§ããŸãã
import 'reflect-metadata';
ãã®ã€ã³ããŒãã¹ããŒãã¡ã³ãã¯ããã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã§äœ¿çšãããå¿
èŠãªReflectAPIãããªãã£ã«ãããããéåžžã«éèŠã§ãã ãã®ã€ã³ããŒããå¿ãããšãã³ãŒããæ£ããæ©èœãããã©ã³ã¿ã€ã ãšã©ãŒãçºçããå¯èœæ§ããããŸãã
ãã³ã¬ãŒã¿ã䜿çšããã¡ã¿ããŒã¿ã®æ·»ä»
reflect-metadataã©ã€ãã©ãªã¯ããªããžã§ã¯ãã«ã¡ã¿ããŒã¿ãæ·»ä»ããããã®Reflect.defineMetadata颿°ãæäŸããŸãã ãã ãããã³ã¬ãŒã¿ã䜿çšããŠã¡ã¿ããŒã¿ãå®çŸ©ããæ¹ãäžè¬çã§äŸ¿å©ã§ãã Reflect.metadataãã³ã¬ãŒã¿ãã¡ã¯ããªã¯ããã³ã¬ãŒã¿ã䜿çšããŠã¡ã¿ããŒã¿ãå®çŸ©ããããã®ç°¡æœãªæ¹æ³ãæäŸããŸãã
次ã«äŸã瀺ããŸãã
import 'reflect-metadata';
const formatMetadataKey = Symbol("format");
function format(formatString: string) {
return Reflect.metadata(formatMetadataKey, formatString);
}
function getFormat(target: any, propertyKey: string) {
return Reflect.getMetadata(formatMetadataKey, target, propertyKey);
}
class Example {
@format("Hello, %s")
greeting: string = "World";
greet() {
let formatString = getFormat(this, "greeting");
return formatString.replace("%s", this.greeting);
}
}
let example = new Example();
console.log(example.greet()); // Output: Hello, World
ãã®äŸã§ã¯ã@formatãã³ã¬ãŒã¿ã䜿çšããŠãæžåŒæåå"Hello, %s"ãExampleã¯ã©ã¹ã®greetingããããã£ã«é¢é£ä»ããŠããŸãã getFormat颿°ã¯ãReflect.getMetadataã䜿çšããŠããã®ã¡ã¿ããŒã¿ãã©ã³ã¿ã€ã æã«ååŸããŸãã æ¬¡ã«ãgreetã¡ãœããã¯ãã®ã¡ã¿ããŒã¿ã䜿çšããŠãæšæ¶ã¡ãã»ãŒãžã®æžåŒãèšå®ããŸãã
Reflectã¡ã¿ããŒã¿API
reflect-metadataã©ã€ãã©ãªã¯ãã¡ã¿ããŒã¿ãæäœããããã®ããã€ãã®é¢æ°ãæäŸããŸãã
Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey?)ïŒãªããžã§ã¯ããŸãã¯ããããã£ã«ã¡ã¿ããŒã¿ãæ·»ä»ããŸããReflect.getMetadata(metadataKey, target, propertyKey?)ïŒãªããžã§ã¯ããŸãã¯ããããã£ããã¡ã¿ããŒã¿ãååŸããŸããReflect.hasMetadata(metadataKey, target, propertyKey?)ïŒãªããžã§ã¯ããŸãã¯ããããã£ã«ã¡ã¿ããŒã¿ãååšãããã©ããã確èªããŸããReflect.deleteMetadata(metadataKey, target, propertyKey?)ïŒãªããžã§ã¯ããŸãã¯ããããã£ããã¡ã¿ããŒã¿ãåé€ããŸããReflect.getMetadataKeys(target, propertyKey?)ïŒãªããžã§ã¯ããŸãã¯ããããã£ã§å®çŸ©ããããã¹ãŠã®ã¡ã¿ããŒã¿ããŒã®é åãè¿ããŸããReflect.getOwnMetadataKeys(target, propertyKey?)ïŒãªããžã§ã¯ããŸãã¯ããããã£ã«çŽæ¥å®çŸ©ããããã¹ãŠã®ã¡ã¿ããŒã¿ããŒã®é åãè¿ããŸãïŒç¶æ¿ãããã¡ã¿ããŒã¿ãé€ãïŒã
ãŠãŒã¹ã±ãŒã¹ãšå®çšçãªäŸ
ãã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã¯ãææ°ã®JavaScriptéçºã«å€æ°ã®ã¢ããªã±ãŒã·ã§ã³ããããŸãã ããã€ãã®äŸã次ã«ç€ºããŸãã
äŸåæ§æ³šå ¥
äŸåæ§æ³šå ¥ïŒDIïŒã¯ãã¯ã©ã¹ãããèªäœãäœæããã®ã§ã¯ãªããäŸåé¢ä¿ãã¯ã©ã¹ã«æäŸããããšã«ãããã³ã³ããŒãã³ãéã®ç·©ãããªçµåãä¿é²ããèšèšãã¿ãŒã³ã§ãã ãã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã䜿çšããŠãJavaScriptã§DIã³ã³ãããå®è£ ã§ããŸãã
UserRepositoryã«äŸåããUserServiceããããšããŸãã ãã³ã¬ãŒã¿ã䜿çšããŠäŸåé¢ä¿ãæå®ããDIã³ã³ããã䜿çšããŠã©ã³ã¿ã€ã ã§è§£æ±ºã§ããŸãã
import 'reflect-metadata';
const Injectable = (): ClassDecorator => {
return (target: any) => {
Reflect.defineMetadata('design:paramtypes', [], target);
};
};
const Inject = (token: any): ParameterDecorator => {
return (target: any, propertyKey: string | symbol, parameterIndex: number) => {
let existingParameters: any[] = Reflect.getOwnMetadata('design:paramtypes', target, propertyKey) || [];
existingParameters[parameterIndex] = token;
Reflect.defineMetadata('design:paramtypes', existingParameters, target, propertyKey);
};
};
class UserRepository {
getUsers() {
return ['user1', 'user2'];
}
}
@Injectable()
class UserService {
private userRepository: UserRepository;
constructor(@Inject(UserRepository) userRepository: UserRepository) {
this.userRepository = userRepository;
}
getUsers() {
return this.userRepository.getUsers();
}
}
// Simple DI Container
class Container {
private static dependencies = new Map();
static register(key: any, concrete: { new(...args: any[]): T }): void {
Container.dependencies.set(key, concrete);
}
static resolve(key: any): T {
const concrete = Container.dependencies.get(key);
if (!concrete) {
throw new Error(`No binding found for ${key}`);
}
const paramtypes = Reflect.getMetadata('design:paramtypes', concrete) || [];
const dependencies = paramtypes.map((param: any) => Container.resolve(param));
return new concrete(...dependencies);
}
}
// Register Dependencies
Container.register(UserRepository, UserRepository);
Container.register(UserService, UserService);
// Resolve UserService
const userService = Container.resolve(UserService);
console.log(userService.getUsers()); // Output: ['user1', 'user2']
ãã®äŸã§ã¯ã@Injectableãã³ã¬ãŒã¿ã¯æ³šå
¥ã§ããã¯ã©ã¹ãããŒã¯ãã@Injectãã³ã¬ãŒã¿ã¯ã³ã³ã¹ãã©ã¯ã¿ã®äŸåé¢ä¿ãæå®ããŸãã Containerã¯ã©ã¹ã¯ãåçŽãªDIã³ã³ãããšããŠæ©èœãããã³ã¬ãŒã¿ã§å®çŸ©ãããã¡ã¿ããŒã¿ã«åºã¥ããŠäŸåé¢ä¿ã解決ããŸãã
ã·ãªã¢ã«åãšãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³
ãã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã䜿çšããŠããªããžã§ã¯ãã®ã·ãªã¢ã«åãšãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ããã»ã¹ãã«ã¹ã¿ãã€ãºã§ããŸãã ããã¯ããªããžã§ã¯ããJSONãXMLãªã©ã®ããŸããŸãªããŒã¿åœ¢åŒã«ãããã³ã°ãããããã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ã®åã«ããŒã¿ãæ€èšŒãããããã®ã«åœ¹ç«ã¡ãŸãã
ã¯ã©ã¹ãJSONã«ã·ãªã¢ã«åããããç¹å®ã®ããããã£ãé€å€ããããååã倿ŽããããããšããŸãã ãã³ã¬ãŒã¿ã䜿çšããŠã·ãªã¢ã«åã«ãŒã«ãæå®ããã¡ã¿ããŒã¿ã䜿çšããŠã·ãªã¢ã«åãå®è¡ã§ããŸãã
import 'reflect-metadata';
const Exclude = (): PropertyDecorator => {
return (target: any, propertyKey: string | symbol) => {
Reflect.defineMetadata('serialize:exclude', true, target, propertyKey);
};
};
const Rename = (newName: string): PropertyDecorator => {
return (target: any, propertyKey: string | symbol) => {
Reflect.defineMetadata('serialize:rename', newName, target, propertyKey);
};
};
class User {
@Exclude()
id: number;
@Rename('fullName')
name: string;
email: string;
constructor(id: number, name: string, email: string) {
this.id = id;
this.name = name;
this.email = email;
}
}
function serialize(obj: any): string {
const serialized: any = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const exclude = Reflect.getMetadata('serialize:exclude', obj, key);
if (exclude) {
continue;
}
const rename = Reflect.getMetadata('serialize:rename', obj, key);
const newKey = rename || key;
serialized[newKey] = obj[key];
}
}
return JSON.stringify(serialized);
}
const user = new User(1, 'John Doe', 'john.doe@example.com');
const serializedUser = serialize(user);
console.log(serializedUser); // Output: {"fullName":"John Doe","email":"john.doe@example.com"}
ãã®äŸã§ã¯ã@Excludeãã³ã¬ãŒã¿ã¯idããããã£ãã·ãªã¢ã«åããé€å€ããããã«ããŒã¯ãã@Renameãã³ã¬ãŒã¿ã¯nameããããã£ãfullNameã«å€æŽããŸãã serialize颿°ã¯ã¡ã¿ããŒã¿ã䜿çšããŠãå®çŸ©ãããã«ãŒã«ã«åŸã£ãŠã·ãªã¢ã«åãå®è¡ããŸãã
æ€èšŒ
ãã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã䜿çšããŠãã¯ã©ã¹ãšããããã£ã®æ€èšŒããžãã¯ãå®è£ ã§ããŸãã ããã¯ãããŒã¿ãåŠçãŸãã¯ä¿åãããåã«ãç¹å®ã®åºæºãæºãããŠããããšã確èªããã®ã«åœ¹ç«ã¡ãŸãã
ããããã£ã空ã§ãªãããšããŸãã¯ç¹å®ã®æ£èŠè¡šçŸã«äžèŽããããšãæ€èšŒãããšããŸãã ãã³ã¬ãŒã¿ã䜿çšããŠæ€èšŒã«ãŒã«ãæå®ããã¡ã¿ããŒã¿ã䜿çšããŠæ€èšŒãå®è¡ã§ããŸãã
import 'reflect-metadata';
const Required = (): PropertyDecorator => {
return (target: any, propertyKey: string | symbol) => {
Reflect.defineMetadata('validate:required', true, target, propertyKey);
};
};
const Pattern = (regex: RegExp): PropertyDecorator => {
return (target: any, propertyKey: string | symbol) => {
Reflect.defineMetadata('validate:pattern', regex, target, propertyKey);
};
};
class Product {
@Required()
name: string;
@Pattern(/^\d+$/)
price: string;
constructor(name: string, price: string) {
this.name = name;
this.price = price;
}
}
function validate(obj: any): string[] {
const errors: string[] = [];
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const required = Reflect.getMetadata('validate:required', obj, key);
if (required && !obj[key]) {
errors.push(`${key} is required`);
}
const pattern = Reflect.getMetadata('validate:pattern', obj, key);
if (pattern && !pattern.test(obj[key])) {
errors.push(`${key} must match ${pattern}`);
}
}
}
return errors;
}
const product = new Product('', 'abc');
const errors = validate(product);
console.log(errors); // Output: ["name is required", "price must match /^\d+$/"]
ãã®äŸã§ã¯ã@Requiredãã³ã¬ãŒã¿ã¯nameããããã£ãå¿
é ãšããŠããŒã¯ãã@Patternãã³ã¬ãŒã¿ã¯priceããããã£ãäžèŽããå¿
èŠãããæ£èŠè¡šçŸãæå®ããŸãã validate颿°ã¯ã¡ã¿ããŒã¿ã䜿çšããŠæ€èšŒãå®è¡ãããšã©ãŒã®é
åãè¿ããŸãã
AOPïŒã¢ã¹ãã¯ãæåããã°ã©ãã³ã°ïŒ
AOPã¯ãã¯ãã¹ã»ã«ããã£ã³ã°ã»ã³ã³ãµãŒã³ã®åé¢ãå¯èœã«ããããšã§ãã¢ãžã¥ãŒã«æ§ãé«ããããšãç®çãšããããã°ã©ãã³ã°ãã©ãã€ã ã§ãã ãã³ã¬ãŒã¿ã¯ãAOPã®ã·ããªãªã«èªç¶ã«åããŸãã ããšãã°ããã®ã³ã°ãç£æ»ãã»ãã¥ãªãã£ãã§ãã¯ã¯ããã³ã¬ãŒã¿ãšããŠå®è£ ããã³ã¢ã¡ãœããããžãã¯ã倿Žããããšãªãã¡ãœããã«é©çšã§ããŸãã
äŸïŒãã³ã¬ãŒã¿ã䜿çšããŠãã®ã³ã°ã¢ã¹ãã¯ããå®è£ ããŸãã
import 'reflect-metadata';
function LogMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Entering method: ${propertyKey} with arguments: ${JSON.stringify(args)}`);
const result = originalMethod.apply(this, args);
console.log(`Exiting method: ${propertyKey} with result: ${result}`);
return result;
};
return descriptor;
}
class Calculator {
@LogMethod
add(a: number, b: number): number {
return a + b;
}
@LogMethod
subtract(a: number, b: number): number {
return a - b;
}
}
const calculator = new Calculator();
calculator.add(5, 3);
calculator.subtract(10, 2);
// Output:
// Entering method: add with arguments: [5,3]
// Exiting method: add with result: 8
// Entering method: subtract with arguments: [10,2]
// Exiting method: subtract with result: 8
ãã®ã³ãŒãã¯ãaddããã³subtractã¡ãœããã®ãšã³ããªãã€ã³ããšãšã°ãžãããã€ã³ãããã°ã«èšé²ãããã®ã³ã°ã³ã³ãµãŒã³ãèšç®æ©ã®ã³ã¢æ©èœãã广çã«åé¢ããŸãã
ãã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã䜿çšããããšã®ã¡ãªãã
JavaScriptã§ãã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã䜿çšãããšãããã€ãã®å©ç¹ãåŸãããŸãã
- ã³ãŒãã®å¯èªæ§ã®åäžïŒãã³ã¬ãŒã¿ã¯ãã¯ã©ã¹ãšãã®ã¡ã³ããŒã®åäœã倿ŽãŸãã¯æ¡åŒµããããã®ç°¡æœã§å®£èšçãªæ¹æ³ãæäŸããã³ãŒããèªã¿ãããçè§£ããããããŸãã
- ã¢ãžã¥ãŒã«æ§ã®åäžïŒãã³ã¬ãŒã¿ã¯ãã³ã³ãµãŒã³ã®åé¢ãä¿é²ããã¯ãã¹ã»ã«ããã£ã³ã°ã»ã³ã³ãµãŒã³ãåé¢ããã³ãŒãã®éè€ãåé¿ããããšãã§ããŸãã
- ä¿å®æ§ã®åäžïŒã³ã³ãµãŒã³ãåé¢ããã³ãŒãã®éè€ãæžããããšã§ããã³ã¬ãŒã¿ã¯ã³ãŒãã®ä¿å®ãšæŽæ°ã容æã«ããŸãã
- æè»æ§ã®åäžïŒã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã䜿çšãããšãã©ã³ã¿ã€ã æã«ã¡ã¿ããŒã¿ã«ã¢ã¯ã»ã¹ã§ãããããããæè»ã§èšå®å¯èœãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã
- AOPã®æå¹åïŒãã³ã¬ãŒã¿ã¯ãã³ã¢ããžãã¯ã倿Žããããšãªããã¡ãœããã«ã¢ã¹ãã¯ããé©çšã§ããããã«ããããšã§ãAOPã容æã«ããŸãã
課é¡ãšèæ ®äºé
ãã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã¯å€ãã®å©ç¹ãæäŸããŸãããèæ ®ãã¹ã課é¡ãšèæ ®äºé ãããã€ããããŸãã
- ããã©ãŒãã³ã¹ãªãŒããŒãããïŒã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã¯ãç¹ã«ãã䜿çšãããå Žåã«ãããçšåºŠã®ããã©ãŒãã³ã¹ãªãŒããŒããããå°å ¥ããå¯èœæ§ããããŸãã
- è€éãïŒãã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ãçè§£ããŠäœ¿çšããã«ã¯ãJavaScriptãš
reflect-metadataã©ã€ãã©ãªãããæ·±ãçè§£ããå¿ èŠããããŸãã - ãããã°ïŒãã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã䜿çšããã³ãŒãã®ãããã°ã¯ãåŸæ¥ã®ã³ãŒãã®ãããã°ãããå°é£ãªå ŽåããããŸãã
- äºææ§ïŒãã³ã¬ãŒã¿ã¯ãŸã Stage 2 ECMAScriptææ¡ã§ããããã®å®è£ ã¯ããŸããŸãªJavaScriptç°å¢ã§ç°ãªãå ŽåããããŸãã TypeScriptã¯åªãããµããŒããæäŸããŠããŸãããã©ã³ã¿ã€ã ããªãã£ã«ãäžå¯æ¬ ã§ããããšãå¿ããªãã§ãã ããã
ãã¹ããã©ã¯ãã£ã¹
ãã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã广çã«äœ¿çšããã«ã¯ã次ã®ãã¹ããã©ã¯ãã£ã¹ãæ€èšããŠãã ããã
- ãã³ã¬ãŒã¿ã¯æ§ããã«äœ¿çšããŠãã ããïŒã³ãŒãã®å¯èªæ§ãã¢ãžã¥ãŒã«æ§ããŸãã¯ä¿å®æ§ã®ç¹ã§æç¢ºãªã¡ãªãããããå Žåã«ã®ã¿ããã³ã¬ãŒã¿ã䜿çšããŸãã ãã³ã¬ãŒã¿ãä¹±çšãããšãã³ãŒããè€éã«ãªãããããã°ãé£ãããªãå¯èœæ§ããããããä¹±çšããªãã§ãã ããã
- ãã³ã¬ãŒã¿ãã·ã³ãã«ã«ä¿ã€ïŒãã³ã¬ãŒã¿ãåäžã®è²¬ä»»ã«éäžãããŸãã è€æ°ã®ã¿ã¹ã¯ãå®è¡ããè€éãªãã³ã¬ãŒã¿ãäœæããªãã§ãã ããã
- ãã³ã¬ãŒã¿ãææžåããïŒåãã³ã¬ãŒã¿ã®ç®çãšäœ¿çšæ³ãæç¢ºã«ææžåããŸãã ããã«ãããä»ã®éçºè ãã³ãŒããçè§£ããŠäœ¿çšããããšã容æã«ãªããŸãã
- ãã³ã¬ãŒã¿ã培åºçã«ãã¹ãããïŒãã³ã¬ãŒã¿ãæ£ããæ©èœããäºæããªãå¯äœçšãçºçããªãããšã確èªããããã«ããã³ã¬ãŒã¿ã培åºçã«ãã¹ãããŸãã
- äžè²«ããåœåèŠåã䜿çšããïŒã³ãŒãã®å¯èªæ§ãåäžãããããã«ããã³ã¬ãŒã¿ã®äžè²«ããåœåèŠåãæ¡çšããŸãã ããšãã°ããã¹ãŠã®ãã³ã¬ãŒã¿åã«
@ããã¬ãã£ãã¯ã¹ãšããŠä»ããããšãã§ããŸãã
ãã³ã¬ãŒã¿ã®ä»£æ¿ææ®µ
ãã³ã¬ãŒã¿ã¯ãã¯ã©ã¹ãšã¡ãœããã«æ©èœã远å ããããã®åŒ·åãªã¡ã«ããºã ãæäŸããŸããããã³ã¬ãŒã¿ãå©çšã§ããªãå Žåãé©åã§ãªãå Žåã«ã代æ¿ã¢ãããŒãã䜿çšã§ããŸãã
é«é颿°
é«é颿°ïŒHOFïŒã¯ãä»ã®é¢æ°ãåŒæ°ãšããŠåãåãããçµæãšããŠé¢æ°ãè¿ã颿°ã§ãã HOFã¯ããã®ã³ã°ãæ€èšŒãæ¿èªãªã©ããã³ã¬ãŒã¿ãšåããã¿ãŒã³ã®å€ããå®è£ ããããã«äœ¿çšã§ããŸãã
ããã¯ã¹ã€ã³
ããã¯ã¹ã€ã³ã¯ãä»ã®ã¯ã©ã¹ãšæ§æããããšã«ãããã¯ã©ã¹ã«æ©èœã远å ããæ¹æ³ã§ãã ããã¯ã¹ã€ã³ã䜿çšããŠãè€æ°ã®ã¯ã©ã¹éã§ã³ãŒããå ±æããã³ãŒãã®éè€ãåé¿ã§ããŸãã
ã¢ã³ããŒããã
ã¢ã³ããŒãããã¯ãå®è¡æã«æ¢åã®ã³ãŒãã®åäœã倿Žããææ³ã§ãã ã¢ã³ããŒãããã¯ããœãŒã¹ã³ãŒãã倿Žããããšãªããã¯ã©ã¹ãšã¡ãœããã«æ©èœã远å ããããã«äœ¿çšã§ããŸãã ãã ããã¢ã³ããŒãããã¯å±éºãªå Žåããããäºæããªãå¯äœçšãåŒãèµ·ãããã³ãŒãã®ä¿å®ãããå°é£ã«ããå¯èœæ§ããããããæ³šæããŠäœ¿çšããå¿ èŠããããŸãã
çµè«
JavaScriptãã³ã¬ãŒã¿ã¯ãã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ãšçµã¿åãããããšã§ãã³ãŒãã®ã¢ãžã¥ãŒã«æ§ãä¿å®æ§ãããã³æè»æ§ã匷åããããã®åŒ·åãªããŒã«ã»ãããæäŸããŸãã ã©ã³ã¿ã€ã ã¡ã¿ããŒã¿ã¢ã¯ã»ã¹ãå¯èœã«ããããšã«ãããäŸåæ§æ³šå ¥ãã·ãªã¢ã«åãæ€èšŒãããã³AOPãªã©ã®é«åºŠãªæ©èœãè§£ãæŸã¡ãŸãã ããã©ãŒãã³ã¹ãªãŒããŒããããè€éããªã©ãèæ ®ãã¹ã課é¡ããããŸããããã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã䜿çšããããšã®ã¡ãªããã¯ãå€ãã®å Žåããã¡ãªãããäžåããŸãã ãã¹ããã©ã¯ãã£ã¹ã«åŸããä»£æ¿ææ®µãçè§£ããããšã«ãããéçºè ã¯ãããã®æè¡ã广çã«æŽ»çšããŠãããå ç¢ã§ã¹ã±ãŒã©ãã«ãªJavaScriptã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã JavaScriptãé²åãç¶ããã«ã€ããŠããã³ã¬ãŒã¿ãšã¡ã¿ããŒã¿ãªãã¬ã¯ã·ã§ã³ã¯ãææ°ã®Webéçºã«ãããŠãè€éãã管çããã³ãŒãã®åå©çšãä¿é²ããããã«ãŸããŸãéèŠã«ãªãå¯èœæ§ããããŸãã
ãã®èšäºã§ã¯ãJavaScriptãã³ã¬ãŒã¿ãã¡ã¿ããŒã¿ãããã³ãªãã¬ã¯ã·ã§ã³ã®å æ¬çãªæŠèŠãæäŸãããã®æ§æããŠãŒã¹ã±ãŒã¹ãããã³ãã¹ããã©ã¯ãã£ã¹ã«ã€ããŠèª¬æããŸãã ãããã®æŠå¿µãçè§£ããããšã«ãããéçºè ã¯JavaScriptã®å¯èœæ§ãæå€§éã«åŒãåºãããã匷åã§ä¿å®æ§ã®é«ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã
ãããã®ææ³ãæ¡çšããããšã§ãäžçäžã®éçºè ã¯ãããã¢ãžã¥ãŒã«åãããä¿å®æ§ãé«ããã¹ã±ãŒã©ãã«ãªJavaScriptãšã³ã·ã¹ãã ã«è²¢ç®ã§ããŸãã